﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using Autodesk.Revit.DB;
using DataBase;

namespace DBService
{
	public class DbWall : DbObject
	{
		[Category("属性")]
		[Description("厚度")]
		[DisplayName("厚度(mm)")]
		[ReadOnly(true)]
		public double Thick
		{
			get
			{
				return this.mThick;
			}
			set
			{
				this.mThick = value;
			}
		}

		[Category("属性")]
		[Description("凸度")]
		[DisplayName("凸度")]
		[ReadOnly(true)]
		public double Bulge
		{
			get
			{
				return this.mBulge;
			}
			set
			{
				this.mBulge = value;
			}
		}

		[Category("属性")]
		[Description("起点")]
		[DisplayName("起点")]
		[ReadOnly(true)]
		public XYZ StartPt
		{
			get
			{
				return this.mStartPt;
			}
			set
			{
				this.mStartPt = value;
			}
		}

		[Category("属性")]
		[Description("终点")]
		[DisplayName("终点")]
		[ReadOnly(true)]
		public XYZ EndPt
		{
			get
			{
				return this.mEndPt;
			}
			set
			{
				this.mEndPt = value;
			}
		}

		[Category("属性")]
		[Description("高度")]
		[DisplayName("高度(mm)")]
		[ReadOnly(true)]
		public double Height
		{
			get
			{
				return this.mHeight;
			}
			set
			{
				this.mHeight = value;
			}
		}

		[Category("属性")]
		[Description("建筑模型Id")]
		[DisplayName("建筑模型Id")]
		[ReadOnly(true)]
		public int RacId
		{
			get
			{
				return this.mRacId;
			}
			set
			{
				this.mRacId = value;
			}
		}

		[Category("属性")]
		[Description("结构模型Id")]
		[DisplayName("结构模型Id")]
		[ReadOnly(true)]
		public int RstId
		{
			get
			{
				return this.mRstId;
			}
			set
			{
				this.mRstId = value;
			}
		}

		[Category("属性")]
		[Description("洞口集合")]
		[DisplayName("洞口集合")]
		[ReadOnly(true)]
		public List<DbOpening> OpeningList
		{
			get
			{
				return this.mOpeningList;
			}
		}

		[Category("属性")]
		[Description("建筑模型路径")]
		[DisplayName("建筑模型路径")]
		[ReadOnly(true)]
		public string ArchPath
		{
			get
			{
				return DbProject.GetFromDB(this.mProjectId, BimServerDB.Default).RacFilePath;
			}
		}

		[Category("属性")]
		[Description("结构模型路径")]
		[DisplayName("结构模型路径")]
		[ReadOnly(true)]
		public string RstPath
		{
			get
			{
				return DbProject.GetFromDB(this.mProjectId, BimServerDB.Default).RstFilePath;
			}
		}

		public DbWall(int projectId, int racId, int rstId, XYZ startPt, XYZ endPt, double bulge, double thick, double height, List<DbOpening> openingList)
		{
			this.mProjectId = projectId;
			this.mStartPt = startPt;
			this.mEndPt = endPt;
			this.mBulge = bulge;
			this.mThick = thick;
			this.mRacId = racId;
			this.mRstId = rstId;
			this.mHeight = height;
			this.mOpeningList = openingList;
		}

		public DbWall(int projectId, int racId, int rstId, XYZ startPt, XYZ endPt, double bulge, double thick, double height)
		{
			this.mProjectId = projectId;
			this.mStartPt = startPt;
			this.mEndPt = endPt;
			this.mBulge = bulge;
			this.mThick = thick;
			this.mRacId = racId;
			this.mRstId = rstId;
			this.mHeight = height;
		}

		public static void Clear(DbProject project)
		{
			foreach (DbWall dbWall in DbWall.GetByProject(project))
			{
				dbWall.RemoveFromDb();
			}
		}

		public static List<DbWall> GetByProject(DbProject project)
		{
			List<DbWall> result;
			try
			{
				if (project.Database.Connection.State == ConnectionState.Closed)
				{
					project.Database.Connection.Open();
				}
				List<DbWall> list = new List<DbWall>();
				string sql = string.Format("SELECT Id,ProjectId,RacID,RstID,StartPtX,StartPtY,StartPtZ,EndPtX,EndPtY,EndPtZ,Bulge,Thickness,Height FROM tbwall WHERE ProjectId={0}", project.Id);
				DataTable dataTable = project.Database.ExecQuery(sql);
				if (project.Database.Connection.State == ConnectionState.Open)
				{
					project.Database.Connection.Close();
				}
				if (dataTable == null)
				{
					result = null;
				}
				else
				{
					for (int i = 0; i < dataTable.Rows.Count; i++)
					{
						int num = Convert.ToInt32(dataTable.Rows[i]["Id"]);
						int projectId = Convert.ToInt32(dataTable.Rows[i]["ProjectId"]);
						int racId = Convert.ToInt32(dataTable.Rows[i]["RacID"]);
						int rstId = Convert.ToInt32(dataTable.Rows[i]["RstID"]);
						XYZ startPt = new XYZ(Convert.ToDouble(dataTable.Rows[i]["StartPtX"]), Convert.ToDouble(dataTable.Rows[i]["StartPtY"]), Convert.ToDouble(dataTable.Rows[i]["StartPtZ"]));
						XYZ endPt = new XYZ(Convert.ToDouble(dataTable.Rows[i]["EndPtX"]), Convert.ToDouble(dataTable.Rows[i]["EndPtY"]), Convert.ToDouble(dataTable.Rows[i]["EndPtZ"]));
						double bulge = Convert.ToDouble(dataTable.Rows[i]["Bulge"]);
						double thick = Convert.ToDouble(dataTable.Rows[i]["Thickness"]);
						double height = Convert.ToDouble(dataTable.Rows[i]["Height"]);
						list.Add(new DbWall(projectId, racId, rstId, startPt, endPt, bulge, thick, height, DbWall.GetOpeningsOfWall(num, project.Database))
						{
							mId = num,
							mDatabase = project.Database
						});
					}
					result = list;
				}
			}
			catch (Exception ex)
			{
				if (project.Database.Connection.State == ConnectionState.Open)
				{
					project.Database.Connection.Close();
				}
				throw ex;
			}
			return result;
		}

		public static DbWall GetFromDB(int id, BimServerDB db)
		{
			DbWall result;
			try
			{
				if (db.Connection.State == ConnectionState.Closed)
				{
					db.Connection.Open();
				}
				string sqlStr = string.Format("SELECT ProjectId,RacID,RstID,StartPtX,StartPtY,StartPtZ,EndPtX,EndPtY,EndPtZ,Bulge,Thickness,Height FROM tbwall WHERE ID={0}", id);
				DataTable dataTable = db.ExecQuery(sqlStr);
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				if (dataTable == null)
				{
					result = null;
				}
				else
				{
					int projectId = Convert.ToInt32(dataTable.Rows[0]["ProjectId"]);
					int racId = Convert.ToInt32(dataTable.Rows[0]["RacID"]);
					int rstId = Convert.ToInt32(dataTable.Rows[0]["RstID"]);
					XYZ startPt = new XYZ(Convert.ToDouble(dataTable.Rows[0]["StartPtX"]), Convert.ToDouble(dataTable.Rows[0]["StartPtY"]), Convert.ToDouble(dataTable.Rows[0]["StartPtZ"]));
					XYZ endPt = new XYZ(Convert.ToDouble(dataTable.Rows[0]["EndPtX"]), Convert.ToDouble(dataTable.Rows[0]["EndPtY"]), Convert.ToDouble(dataTable.Rows[0]["EndPtZ"]));
					double bulge = Convert.ToDouble(dataTable.Rows[0]["Bulge"]);
					double thick = Convert.ToDouble(dataTable.Rows[0]["Thickness"]);
					double height = Convert.ToDouble(dataTable.Rows[0]["Height"]);
					result = new DbWall(projectId, racId, rstId, startPt, endPt, bulge, thick, height, DbWall.GetOpeningsOfWall(id, db))
					{
						mId = id,
						mDatabase = db
					};
				}
			}
			catch (Exception ex)
			{
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				throw ex;
			}
			return result;
		}

		private static List<DbOpening> GetOpeningsOfWall(int wallId, IDatabase db)
		{
			List<DbOpening> result;
			try
			{
				if (db.Connection.State == ConnectionState.Closed)
				{
					db.Connection.Open();
				}
				List<DbOpening> list = new List<DbOpening>();
				string sql = string.Format("SELECT OpeningId FROM tbopeningofwall WHERE WallId={0}", wallId);
				DataTable dataTable = db.ExecQuery(sql);
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				for (int i = 0; i < dataTable.Rows.Count; i++)
				{
					DbOpening fromDB = DbOpening.GetFromDB(Convert.ToInt32(dataTable.Rows[i]["OpeningId"]), db);
					list.Add(fromDB);
				}
				result = list;
			}
			catch (Exception ex)
			{
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				throw ex;
			}
			return result;
		}

		public static List<DbWall> GetFromDB(IDatabase db)
		{
			List<DbWall> result;
			try
			{
				if (db.Connection.State == ConnectionState.Closed)
				{
					db.Connection.Open();
				}
				List<DbWall> list = new List<DbWall>();
				string sql = string.Format("SELECT Id,ProjectId,RacID,RstID,StartPtX,StartPtY,StartPtZ,EndPtX,EndPtY,EndPtZ,Bulge,Thickness,Height FROM tbwall", Array.Empty<object>());
				DataTable dataTable = db.ExecQuery(sql);
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				if (dataTable == null)
				{
					result = null;
				}
				else
				{
					for (int i = 0; i < dataTable.Rows.Count; i++)
					{
						int num = Convert.ToInt32(dataTable.Rows[i]["Id"]);
						int projectId = Convert.ToInt32(dataTable.Rows[i]["ProjectId"]);
						int racId = Convert.ToInt32(dataTable.Rows[i]["RacID"]);
						int rstId = Convert.ToInt32(dataTable.Rows[i]["RstID"]);
						XYZ startPt = new XYZ(Convert.ToDouble(dataTable.Rows[i]["StartPtX"]), Convert.ToDouble(dataTable.Rows[i]["StartPtY"]), Convert.ToDouble(dataTable.Rows[i]["StartPtZ"]));
						XYZ endPt = new XYZ(Convert.ToDouble(dataTable.Rows[i]["EndPtX"]), Convert.ToDouble(dataTable.Rows[i]["EndPtY"]), Convert.ToDouble(dataTable.Rows[i]["EndPtZ"]));
						double bulge = Convert.ToDouble(dataTable.Rows[i]["Bulge"]);
						double thick = Convert.ToDouble(dataTable.Rows[i]["Thickness"]);
						double height = Convert.ToDouble(dataTable.Rows[i]["Height"]);
						list.Add(new DbWall(projectId, racId, rstId, startPt, endPt, bulge, thick, height, DbWall.GetOpeningsOfWall(num, db))
						{
							mId = num,
							mDatabase = db
						});
					}
					result = list;
				}
			}
			catch (Exception ex)
			{
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				throw ex;
			}
			return result;
		}

		public override void AddToDb(IDatabase db)
		{
			try
			{
				if (db.Connection.State == ConnectionState.Closed)
				{
					db.Connection.Open();
				}
				string sql = string.Format("INSERT INTO tbwall (Thickness,RacID,RstID,StartPtX,StartPtY,StartPtZ,EndPtX,EndPtY,EndPtZ,Bulge,ProjectId,Height) VALUES ({0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11})", new object[]
				{
					this.mThick,
					this.mRacId,
					this.mRstId,
					this.mStartPt.X,
					this.mStartPt.Y,
					this.mStartPt.Z,
					this.mEndPt.X,
					this.mEndPt.Y,
					this.mEndPt.Z,
					this.mBulge,
					this.mProjectId,
					this.mHeight
				});
				db.ExecuteCommand(sql);
				string sql2 = string.Format("select max(Id) from tbwall", Array.Empty<object>());
				DataTable dataTable = db.ExecQuery(sql2);
				this.mId = Convert.ToInt32(dataTable.Rows[0][0]);
				this.mDatabase = db;
				foreach (DbOpening dbOpening in this.mOpeningList)
				{
					dbOpening.AddToDb(db);
					if (db.Connection.State == ConnectionState.Closed)
					{
						db.Connection.Open();
					}
					string sql3 = string.Format("INSERT INTO tbopeningofwall (wallId,OpeningId) VALUES ({0},{1})", base.Id, dbOpening.Id);
					db.ExecuteCommand(sql3);
				}
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (db.Connection.State == ConnectionState.Open)
				{
					db.Connection.Close();
				}
				throw ex;
			}
		}

		public override void UpdateToDb()
		{
			try
			{
				if (base.Database.Connection.State == ConnectionState.Closed)
				{
					base.Database.Connection.Open();
				}
				string sql = string.Format("UPDATE tbwall Thickness={0},RacID={1},RstID={2},StartPtX={3},StartPtY={4},StartPtZ={5},EndPtX={6},EndPtY={7},EndPtZ={8},Bulge={9},ProjectId={10},Height={11} WHERE Id ={12}", new object[]
				{
					this.mThick,
					this.mRacId,
					this.mRstId,
					this.mStartPt.X,
					this.mStartPt.Y,
					this.mStartPt.Z,
					this.mEndPt.X,
					this.mEndPt.Y,
					this.mEndPt.Z,
					this.mBulge,
					this.mProjectId,
					this,
					this.mHeight,
					base.Id
				});
				base.Database.ExecuteCommand(sql);
				if (base.Database.Connection.State == ConnectionState.Open)
				{
					base.Database.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (base.Database.Connection.State == ConnectionState.Open)
				{
					base.Database.Connection.Close();
				}
				throw ex;
			}
		}

		public override void RemoveFromDb()
		{
			try
			{
				if (base.Database.Connection.State == ConnectionState.Closed)
				{
					base.Database.Connection.Open();
				}
				string sql = string.Format("DELETE FROM tbwall WHERE Id = {0}", base.Id);
				base.Database.ExecuteCommand(sql);
				foreach (DbOpening dbOpening in this.OpeningList)
				{
					dbOpening.RemoveFromDb();
					if (base.Database.Connection.State == ConnectionState.Closed)
					{
						base.Database.Connection.Open();
					}
					string sql2 = string.Format("DELETE FROM tbopeningofwall WHERE WallId={0}", base.Id);
					base.Database.ExecuteCommand(sql2);
				}
				if (base.Database.Connection.State == ConnectionState.Open)
				{
					base.Database.Connection.Close();
				}
			}
			catch (Exception ex)
			{
				if (base.Database.Connection.State == ConnectionState.Open)
				{
					base.Database.Connection.Close();
				}
				throw ex;
			}
		}

		public override string ToString()
		{
			return string.Format("结构({0})-建筑({1})", this.mRstId.ToString(), this.mRacId.ToString());
		}

		public static int IsInDb(int projectId, int wallId)
		{
			BimServerDB @default = BimServerDB.Default;
			int result;
			try
			{
				if (@default.Connection.State == ConnectionState.Closed)
				{
					@default.Connection.Open();
				}
				int num = -1;
				string sqlStr = string.Format("select id FROM tbwall WHERE racId = {0} AND ProjectId={1}", wallId, projectId);
				DataTable dataTable = @default.ExecQuery(sqlStr);
				if (@default.Connection.State == ConnectionState.Open)
				{
					@default.Connection.Close();
				}
				if (dataTable != null && dataTable.Rows.Count > 0)
				{
					num = (int)dataTable.Rows[0]["id"];
				}
				result = num;
			}
			catch (Exception ex)
			{
				if (@default.Connection.State == ConnectionState.Open)
				{
					@default.Connection.Close();
				}
				throw ex;
			}
			return result;
		}

		public void AddOpening(DbOpening opening)
		{
			try
			{
				opening.AddToDb(this.mDatabase);
				if (this.mDatabase.Connection.State == ConnectionState.Closed)
				{
					this.mDatabase.Connection.Open();
				}
				string sql = string.Format("INSERT INTO tbopeningofwall (WallId, OpeningId) VALUES ({0},{1})", base.Id, opening.Id);
				this.mDatabase.ExecuteCommand(sql);
				if (this.mDatabase.Connection.State == ConnectionState.Open)
				{
					this.mDatabase.Connection.Close();
				}
				this.mOpeningList.Add(opening);
			}
			catch (Exception ex)
			{
				if (this.mDatabase.Connection.State == ConnectionState.Open)
				{
					this.mDatabase.Connection.Close();
				}
				throw ex;
			}
		}

		private int mProjectId;

		private double mThick;

		private double mBulge;

		private XYZ mStartPt;

		private XYZ mEndPt;

		private double mHeight;

		private int mRacId;

		private int mRstId;

		public List<DbOpening> mOpeningList = new List<DbOpening>();
	}
}
